﻿using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using StarsAdmin.Application.OperationLog.Dtos;
using StarsAdmin.Application.Region.Dtos;
using StarsAdmin.Core.App;
using StarsAdmin.Core.Cache;
using StarsAdmin.Core.Consts;
using StarsAdmin.Core.DB.Entities;
using StarsAdmin.Core.Exceptions;
using StarsAdmin.Core.Extensions;
using StarsAdmin.Core.Models;
using StarsAdmin.Repository.Api;
using StarsAdmin.Repository.OperationLog;
using StarsAdmin.Repository.User;

namespace StarsAdmin.Application.OperationLog.Services
{
    public class OperationLogService : IOperationLogService
    {
        private readonly IOperationLogRepository _operationLogRepository;
        private readonly IUserRepository _userRepository;
        private readonly IApiRepository _apiRepository;
        private readonly IMapper _mapper;
        private readonly ICacheService _cache;

        public OperationLogService(IMapper mapper, ICacheService cacheService, IOperationLogRepository oprationLogRepository, IUserRepository userRepository, IApiRepository apiRepository)
        {
            _operationLogRepository = oprationLogRepository;
            _userRepository = userRepository;
            _apiRepository = apiRepository;
            _mapper = mapper;
            _cache = cacheService;
        }

        #region 查询

        public async Task<List<OperationLogDto>> GetAllAsync(BaseQueryInput input)
        {
            var result = await _operationLogRepository.GetAll().AsNoTracking()
              .WhereIf(input != null && input.QueryConditions.Any(), input.QueryConditions)
              .OrderByIf(input != null && input.Sort != null, input.Sort, input.Order != false)
              .ToListAsync();
            return _mapper.Map<List<OperationLogDto>>(result);
        }

        public async Task<Page<OperationLogDto>> GetPageAsync(PageQueryInput input)
        {
            var result = await _operationLogRepository.GetAll().AsNoTracking()
                         .WhereIf(input != null && input.QueryConditions.Any(), input.QueryConditions)
                         .OrderByIf(input != null && input.Sort != null, input.Sort, input.Order != false)
                         .ToPageListAsync(input.CurrentPage, input.PageSize);
            return _mapper.Map<Page<OperationLogDto>>(result);
        }

        public async Task<OperationLogDto?> GetByIdAsync(long id)
        {
            var result = await _operationLogRepository.GetByIdAsync(id);
            return _mapper.Map<OperationLogDto>(result);
        }

        public async Task<List<OperationLogDto>> GetByIdsAsync(long[] ids)
        {
            var result = await _operationLogRepository.GetByIds(ids).ToListAsync();
            return _mapper.Map<List<OperationLogDto>>(result);
        }

        #endregion 查询

        #region 添加

        public void AddLog(AddOperationLogInput input)
        {
            //使用 Task 将日志记录操作放到后台执行
            TaskExtension.Run("操作日志记录", async () =>
            {
                using (var scope = AppHelper.ServiceProvider.CreateScope())
                {
                    var userRepository = scope.ServiceProvider.GetRequiredService<IUserRepository>();
                    var user = await userRepository.GetBy(e => e.UserName == input.UserName).FirstOrDefaultAsync();
                    if (user == null)
                    {
                        throw new NotFoundException("当前用户不存在");
                    }
                    var entity = _mapper.Map<OperationLogEntity>(input);
                    entity.UserId = user.Id;
                    entity.UserName = user.UserName;
                    var apiRepository = scope.ServiceProvider.GetRequiredService<IApiRepository>();
                    var api = await apiRepository.GetBy(e => e.Path == input.ApiPath).FirstOrDefaultAsync();
                    if (api != null)
                    {
                        entity.ApiLabel = api.Label;
                    }
                    var operationLogRepository = scope.ServiceProvider.GetRequiredService<IOperationLogRepository>();
                    await operationLogRepository.AddAndSaveAsync(entity);
                }
            });
        }

        public async Task<bool> AddAsync(AddOperationLogInput input)
        {
            var user = await _userRepository.GetBy(e => e.UserName == input.UserName).FirstOrDefaultAsync();
            if (user == null)
            {
                throw new NotFoundException("当前用户不存在");
            }
            var entity = _mapper.Map<OperationLogEntity>(input);
            entity.UserId = user.Id;
            entity.UserName = user.UserName;
            var api = await _apiRepository.GetBy(e => e.Path == input.ApiPath).FirstOrDefaultAsync();
            if (api != null)
            {
                entity.ApiLabel = api.Label;
            }

            //使用 Task 将日志记录操作放到后台执行
            TaskExtension.Run("操作日志记录", async () =>
            {
                using (var scope = AppHelper.ServiceProvider.CreateScope())
                {
                    var operationLogRepository = scope.ServiceProvider.GetRequiredService<IOperationLogRepository>();
                    await operationLogRepository.AddAndSaveAsync(entity);
                }
            });
            return true;

            //return await _operationLogRepository.AddAndSaveAsync(entity);
        }

        #endregion 添加
    }
}